package com.mioto.ld.component;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.classmate.TypeResolver;
import com.mioto.ld.security.config.JwtConfig;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import springfox.documentation.builders.OperationBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.ResponseMessageBuilder;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiDescription;
import springfox.documentation.service.Operation;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.ApiListingScannerPlugin;
import springfox.documentation.spi.service.contexts.DocumentationContext;
import springfox.documentation.spring.web.readers.operation.CachingOperationNameGenerator;

import java.util.List;

/**
 * @author mioto-qinxj
 * @date 2024/5/13
 * @desc 由于 Spring Security 的登录、登出接口是通过Filter实现，
 * 导致 Swagger 无法获取其信息。这里手动将登录、登出接口注册到Swagger中，
 * 在Swagger-UI才能展示，方便调用。
 */
@Component
public class SpringSecurityAPis implements ApiListingScannerPlugin {
    @Override
    public List<ApiDescription> apply(DocumentationContext documentationContext) {

        Parameter username = new ParameterBuilder()
                .name("username")
                .type(new TypeResolver().resolve(String.class))
                .modelRef(new ModelRef("string"))
                .parameterType("form")
                .defaultValue("admin")
                .build();
        Parameter password = new ParameterBuilder()
                .name("password")
                .type(new TypeResolver().resolve(String.class))
                .modelRef(new ModelRef("string"))
                .parameterType("form")
                .defaultValue("123456")
                .build();
        Parameter clientType = new ParameterBuilder()
                .name("clientType")
                .type(new TypeResolver().resolve(String.class))
                .modelRef(new ModelRef("string"))
                .parameterType("form")
                .defaultValue("web")
                .build();
        Operation loginOperation = new OperationBuilder(new CachingOperationNameGenerator())
                .method(HttpMethod.POST)
                .summary("登录")
                .tags(CollUtil.newHashSet(JwtConfig.tokenHeader))
                .responseMessages(CollUtil.newHashSet(new ResponseMessageBuilder().code(200).message("ok").build()))
                .consumes(CollUtil.newHashSet(MediaType.MULTIPART_FORM_DATA_VALUE))
                .produces(CollUtil.newHashSet(MediaType.APPLICATION_JSON_VALUE))
                .parameters(CollUtil.newArrayList(username,password,clientType))
                .build();
        ApiDescription loginDesc = new ApiDescription("","/login","登录",CollUtil.newArrayList(loginOperation),false);
        return CollUtil.newArrayList(loginDesc);
    }

    @Override
    public boolean supports(DocumentationType documentationType) {
        return DocumentationType.SWAGGER_2.equals(documentationType);
    }
}
